use std::any::Any;
use std::collections::HashMap;
use std::error::Error;
use std::ops::Deref;
use bytes::{Buf, BufMut, BytesMut};
use log::info;

pub trait Encode {
    fn encode(&self, buf: &mut BytesMut);
}

pub trait Decode {
    fn decode(&mut self, buf: &mut BytesMut) -> Result<(), Box<dyn Error>>;
}

pub trait RouteHandle<D: Decode, R: Encode> {
    fn handle(self: Box<Self>, d: D)->R;
}

pub trait RouteHandle2 {
    fn handle(self: Box<Self>)->Box<dyn Encode + 'static>;
}

pub struct DummyRouteHandle {
    pub rh: dyn Fn(dyn Decode + 'static)-> (dyn Encode + 'static)
}

// impl DummyRouteHandle {
//     fn from<F>(f: Box<dyn Fn(dyn Decode + 'static) -> (dyn Encode + 'static)>) -> Box<Self> {
//         Box::new(DummyRouteHandle { rh: f })
//     }
// }

impl <F, D, R> RouteHandle<D, R> for F where F: Fn(D)->R, R:Encode + 'static, D: Decode + 'static {
    fn handle(self: Box<Self>, d: D) -> R {
        (*self)(d)
    }
}

impl <F: Fn(Box<dyn Decode + 'static>) -> Box <dyn Encode + 'static>> RouteHandle2 for F {
    fn handle(self: Box<Self>) -> Box<dyn Encode + 'static> {
        todo!()
    }
}

type RpcData<D: Decode, R: Encode> = Box<dyn RouteHandle<D, R>>;

pub struct Dto<D: Sized> {
    path: String,
    data: D
}

#[derive(Debug, Default)]
pub struct Login {}
impl Encode for Login {
    fn encode(&self, buf: &mut BytesMut) {

    }
}

impl Decode for Login {
    fn decode(&mut self, buf: &mut BytesMut) -> Result<(), Box<dyn Error>> {
        todo!()
    }
}

#[derive(Debug, Default)]
pub struct LoginResp {}

impl Encode for LoginResp {
    fn encode(&self, buf: &mut BytesMut) {

    }
}
impl Decode for LoginResp {
    fn decode(&mut self, buf: &mut BytesMut) -> Result<(), Box<dyn Error>> {
        todo!()
    }
}

#[derive(Debug, Default)]
pub struct TokenLogin {}
impl Decode for TokenLogin {
    fn decode(&mut self, buf: &mut BytesMut) -> Result<(), Box<dyn Error>> {
        todo!()
    }
}

#[test]
fn routHandle2() {
    let mut routeMap: HashMap<&str, Box<dyn RouteHandle2>> = HashMap::new();
    let doTokenLogin= |login: TokenLogin| -> LoginResp {
        LoginResp::default()
    };

    let mut routeMap3: HashMap<&str, Box<dyn RouteHandle<dyn Decode, dyn Encode>>> = HashMap::new();
    // doRouteHandle3(&mut routeMap3, doTokenLogin);
    // routeMap3.insert("/loginToken", doTokenLogin);

    // routeMap.insert("doTokenLogin", Box::new(doTokenLogin));

    // let mut routeMap4: HashMap<&str, Box<DummyRouteHandle>> = HashMap::new();
    // let dd = DummyRouteHandle { rh: doTokenLogin };
    // routeMap4.insert("ddd", doTokenLogin);

    let bytes_mut = BytesMut::with_capacity(1024);
    
    type ClosureType = Box<dyn Fn(dyn Decode + 'static) -> (dyn Encode + 'static)>;

    let mut closures: HashMap<&str, Box<dyn Any>> = HashMap::new();
    closures.insert("sss", Box::new(login));
    closures.insert("ttt", Box::new(doTokenLogin));

    let t = closures.get("sss").unwrap();
    info!("t typeid: {:?}, {:?}, {:?}", t.type_id(), t.deref().type_id(), login.type_id());
    if let Some(f) = t.deref().downcast_ref::<fn(login: Login) -> LoginResp>() {
        info!("Answer:");
    } else {
        info!("no Answer:");
    }

    let tt = closures.get("ttt").unwrap();
    let ttt =  |token_login: TokenLogin| -> LoginResp { LoginResp::default() };
    info!("t typeid2: {:?}, {:?}, {:?}, {:?}", tt.type_id(), tt.deref().type_id(), doTokenLogin.type_id(), ttt.type_id());
    let tt_t = tt.deref();
    if let Some(f) = tt_t.downcast_ref::<fn(TokenLogin) -> LoginResp>() {
        info!("login:");
    } else {
        info!("no login:");
    }

    fn add(x: i32) -> i32 { x + 1 }

    let  func: &dyn Any = &add;
    if let Some(f) = func.downcast_ref::<fn(i32) -> i32>() {
        info!("Result: {}", f(5)); // 输出 6
    } else {
        info!("no Result 333");
    }
}

#[test]
fn ff_test() {
    let mut functions: HashMap<&str, Box<dyn Any>> = HashMap::new();

    // 存储无参函数
    functions.insert("get_answer", Box::new(|| 42) as Box<dyn Any>);

    // 存储带参函数
    functions.insert("multiply", Box::new(|x: i32| x * 2) as Box<dyn Any>);

    // 调用函数
    if let Some(func) = functions.get("get_answer") {
        if let Some(f) = func.downcast_ref::<fn() -> i32>() {
            info!("Answer {}", f());
        } else {
            info!("No Answer");
        }
    }

    if let Some(func) = functions.get("multiply") {
        if let Some(f) = func.downcast_ref::<fn(i32) -> i32>() {
            info!("Result {}", f(10));
        } else {
            info!("No Result");
        }
    }
}

#[test]
fn it_works() {
    let mut bytesMut = BytesMut::with_capacity(10);
    bytesMut.put(&b"helloworld"[..]);
    info!("{:?}", bytesMut);
    info!("bytes length: {}", bytesMut.len());

    bytesMut.advance(10);
    info!("bytes new length: {}", bytesMut.len());

    bytesMut.put(&b"hello world"[..]);
    info!("{:?}", bytesMut);
    info!("bytes length: {}", bytesMut.len());

    // let mut routeMap: HashMap<&str, RpcData<Box<dyn Decode>, dyn Encode + 'static>> = HashMap::new();
    let mut routeMap: HashMap<&str, Box<dyn Any>> = HashMap::new();
    let mut routeList : Vec<Box<dyn Fn(dyn Decode) -> (dyn Encode + 'static)>> = Vec::new();

    // let mut routeMap: HashMap<&str, Box<dyn Fn(dyn Decode) -> (dyn Encode + 'static)>> = HashMap::new();
    // let doLogin : Fn(dyn Decode) -> dyn Encode = |login: Login| -> LoginResp {
    //     LoginResp::default()
    // };

    let rr  = Box::new(login);
    // routeMap.insert("/login", rr);
    // test2(doLogin, &mut routeMap);
    // routeList.push(rr);

    login1(Box::new(TokenLogin::default()));
    let doTokenLogin= |login: TokenLogin| -> LoginResp {
        LoginResp::default()
    };
    test3(doTokenLogin, &mut routeMap);
    let handle = routeMap.get("/login").unwrap();
    if handle.is::<Box<dyn RouteHandle<dyn Decode, dyn Encode>>>() {
        info!("It's a RouteHandle!");
        // (*handle).handle(Login::default())
    } else {
        info!("It's not a RouteHandle!");
    }

    if let Some(marker) = (*handle).downcast_ref::<&dyn RouteHandle<dyn Decode, dyn Encode>>() {
        info!("It's a RouteHandle!");
        // (*marker).handle(Login::default())
    } else {
        info!("It's not a RouteHandle!");
    }
    // routeList.push(Box::new(doTokenLogin));

    // routeMap.insert("/login", 8_i8);
    let mut list: Vec<Box<dyn Any>> = Vec::new();
    let mut mixed_list: Vec<Box<dyn Any>> = Vec::new();
}

#[test]
fn ttt_test() {
    enum FuncParam {
        Zero,
        One(i32),
        Two(i32, i32),
    }

    // 定义返回类型枚举
    enum FuncResult {
        Int(i32),
        String(String),
        Vec(Vec<i32>),
    }

    // 定义可调用 trait
    trait Callable {
        fn call(&self, param: FuncParam) -> FuncResult;
    }

    // 为不同函数实现 Callable
    struct Function0<F>(F);
    impl<F: Fn() -> i32> Callable for Function0<F> {
        fn call(&self, param: FuncParam) -> FuncResult {
            match param {
                FuncParam::Zero => FuncResult::Int((self.0)()),
                _ => panic!("Invalid parameters"),
            }
        }
    }

    struct Function1<F>(F);
    impl<F: Fn(i32) -> String> Callable for Function1<F> {
        fn call(&self, param: FuncParam) -> FuncResult {
            match param {
                FuncParam::One(x) => FuncResult::String((self.0)(x)),
                _ => panic!("Invalid parameters"),
            }
        }
    }


    let mut functions: HashMap<&str, Box<dyn Callable>> = HashMap::new();

    // 添加函数
    functions.insert("get_answer", Box::new(Function0(|| 42)));
    functions.insert("to_string", Box::new(Function1(|x: i32| x.to_string())));

    // 调用函数
    if let Some(func) = functions.get("get_answer") {
        match func.call(FuncParam::Zero) {
            FuncResult::Int(value) => info!("Answer: {}", value),
            _ => unreachable!(),
        }
    }
}

fn login(login: Login)-> LoginResp {
    LoginResp::default()
}

fn login1(login: Box<dyn Decode>)-> Box<(dyn Encode + 'static)> {
    Box::new(LoginResp::default())
}

fn test3<F, D, R>(f: F, routeMap: &mut HashMap<&str, Box<dyn Any>>) where F: Fn(D) -> R + 'static, D: Decode + 'static, R: Encode  + 'static {
    let rr : Box<dyn Any>  = Box::new(f);
    routeMap.insert("/login", rr);
}

// fn test4<F>(f: F, routeMap: &mut HashMap<&str, RpcData<Box<dyn Decode>, dyn Encode>>) where F: Fn(Box<dyn Decode>) -> (dyn Encode + 'static) {
//     let rr : RpcData<Box<dyn Decode>, dyn Encode>  = Box::new(|d: dyn Decode| -> (dyn Encode + 'static) {f(Box::new(d))});
//     routeMap.insert("/login", rr);
// }

fn test2<F, D, R>(f: F, routeMap: &mut HashMap<&str, Box<dyn Fn(D) -> R>>) where F: Fn(D)-> R + 'static, D: Decode, R: Encode {
    let rr: Box<dyn Fn(D) -> R> = Box::new(f);
    routeMap.insert("/login", rr);
}

fn test<F, D, R>(f: F) where F: Fn(D)->R, D: Encode, R: Decode {
    let mut routeMap: HashMap<&str, Box<dyn Fn(D) -> R>> = HashMap::new();
    let rr: Box<dyn Fn(D) -> R> = Box::new(f);
    routeMap.insert("/login", rr);
}
fn d1(str: &str)->&str {
    str 
}

fn d2(str: &str)->&str {
    str
}

fn doRouteHandle2(route: Box<dyn RouteHandle2>) {
    
}

fn doRouteHandle3(map: &mut HashMap<&str, Box<dyn RouteHandle<dyn Decode, dyn Encode>>>, route: fn(dyn Decode) -> dyn Encode) {
    // map.insert("", Box::new(route));
}

pub enum RpcRouter {
    login(fn(Login) -> LoginResp),
}

fn to_route() -> RpcRouter {
    RpcRouter::login(do_login)
}

pub fn do_login(login: Login) -> LoginResp {
    todo!()
}

